﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using SilverlightCountDownTimer.Utils;

namespace SilverlightCountDownTimer.ViewModel
{
    /// <summary>
    /// ViewModel for main view. Contain all view's logic.
    /// </summary>
    public class SilverlightTimerControlViewModel : ViewModelBaseClass.ViewModelBase
    {
        #region Fields
        private System.Windows.Threading.DispatcherTimer _myDispatcherTimer;
        private TimeSpan _eventTimeSpan;
        #endregion

        #region constructor
        public SilverlightTimerControlViewModel()
        {
            _myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();         
            _myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 100); // 100 Miliseconds 
            _myDispatcherTimer.Tick += new EventHandler(myDispatcherTimer_Tick);
        }
        #endregion 

        #region Properties

        public event EventHandler CounterFinish;

        private DateTime _eventTime;
        public DateTime EventTime
        {
            set
            {
                if (null != value)
                {
                    _eventTime = value;
                    InitTime(_eventTime);
                    InitCounter();
                }
                else
                {
                    Description = "Event time was not set";
                }
            }
        }

        private String _eventTimeUrl;
        public String EventTimeUrl
        {
            set
            {
                if (null != value && String.Empty != value)
                {
                    _eventTimeUrl = value;

                    IsolatedStorageManager isolatedStorage = new IsolatedStorageManager();
                    if (!EventTimeCache || !isolatedStorage.ContainsValidEventTime())
                    {
                        FileReader fileReader = new FileReader();
                        fileReader.FileDownloaded += new EventHandler(fileReader_FileDownloaded);
                        fileReader.ReadFileAsync(_eventTimeUrl);
                    }
                    else
                    {
                        EventTime = isolatedStorage.ReadDate();
                    }
                }
            }
        }        
        
        private Boolean _eventTimeCache;
        /// <summary>
        /// Turon on/off caching for event's date.
        /// </summary>
        public Boolean EventTimeCache
        {
            get
            {
                return _eventTimeCache;
            }
            set
            {
                _eventTimeCache = value;
            }
        }

        private int _eventTimeCacheDuration;
        /// <summary>
        /// Number of days when event's date will be cached
        /// </summary>
        public int EventTimeCacheDuration
        {
            get
            {
                return _eventTimeCacheDuration;
            }
            set
            {
                _eventTimeCacheDuration = value;
                if (EventTimeCache)
                {
                    IsolatedStorageManager isolatedStorage = new IsolatedStorageManager();
                    isolatedStorage.SaveCacheDuration(_eventTimeCacheDuration);
                }
            }
        }

        private String _description = String.Empty;
        public String Description
        {
            get
            {
                return _description;
            }
            set
            {
                _description = value;
                base.OnPropertyChanged(this, "Description");
            }
        }

        private String _time = "00:00:00:00:0";
        public String Time
        {
            get
            {
                return _time;
            }
            set
            {
                _time = value;
                base.OnPropertyChanged(this, "Time");
            }
        }

        #endregion

        #region Methods

        void fileReader_FileDownloaded(object sender, EventArgs e)
        {
            if (((DownloadStringCompletedEventArgs)e).Error != null ||
                ((DownloadStringCompletedEventArgs)e).Result == String.Empty)
                return;
                 
            string result = ((DownloadStringCompletedEventArgs)e).Result;
            DateTime eventTime = DateTime.MinValue;
            try
            {
                eventTime = DateTime.Parse(result);
            }
            catch (Exception)
            {
                Description = "Event time url was not set correctly";
                return;
            }
            if (eventTime != DateTime.MinValue)
            {
                IsolatedStorageManager isolatedStorage = new IsolatedStorageManager();
                isolatedStorage.SaveDate(eventTime);
                EventTime = eventTime;
            }
        }

        private void InitTime(DateTime eventDate)
        {
            _eventTimeSpan = _eventTime - DateTime.Now;

            Time = String.Format("{0:00}:{1:00}:{2:00}:{3:00}:{4:0}", 
                _eventTimeSpan.Days, _eventTimeSpan.Hours, _eventTimeSpan.Minutes, _eventTimeSpan.Seconds,
                _eventTimeSpan.Milliseconds/100);
        }

        private void InitCounter()
        {
            
            if (!_myDispatcherTimer.IsEnabled)
            {
                _myDispatcherTimer.Start();
            }       
        }

        void myDispatcherTimer_Tick(object sender, EventArgs e)
        {
            _eventTimeSpan = _eventTime - DateTime.Now;
            Time = String.Format("{0:00}:{1:00}:{2:00}:{3:00}:{4:0}",
                 _eventTimeSpan.Days, _eventTimeSpan.Hours, _eventTimeSpan.Minutes, _eventTimeSpan.Seconds,
                 _eventTimeSpan.Milliseconds / 100);

            if (_eventTime < DateTime.Now)
            {
                ((DispatcherTimer)sender).Stop();
                Time = "00:00:00:00:0";
                if (null != CounterFinish)
                {
                    CounterFinish(this, EventArgs.Empty);
                }
            }
        }
        #endregion
    }
}

